That way, different pipelines can draw different kinds of data.
GObject parent_instance;
};
-G_DEFINE_TYPE (GskVulkanBlendPipeline, gsk_vulkan_blend_pipeline, G_TYPE_OBJECT)
+typedef struct _GskVulkanVertex GskVulkanVertex;
+
+struct _GskVulkanVertex
+{
+ float x;
+ float y;
+ float tex_x;
+ float tex_y;
+};
+
+G_DEFINE_TYPE (GskVulkanBlendPipeline, gsk_vulkan_blend_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static void
gsk_vulkan_blend_pipeline_finalize (GObject *gobject)
{
return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_BLEND_PIPELINE, layout, shader_name, render_pass);
}
+
+gsize
+gsk_vulkan_blend_pipeline_count_vertex_data (GskVulkanBlendPipeline *pipeline)
+{
+ return sizeof (GskVulkanVertex) * 6;
+}
+
+void
+gsk_vulkan_blend_pipeline_collect_vertex_data (GskVulkanBlendPipeline *pipeline,
+ guchar *data,
+ const graphene_rect_t *rect)
+{
+ GskVulkanVertex *vertices = (GskVulkanVertex *) data;
+
+ vertices[0] = (GskVulkanVertex) { rect->origin.x, rect->origin.y, 0.0, 0.0 };
+ vertices[1] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y, 1.0, 0.0 };
+ vertices[2] = (GskVulkanVertex) { rect->origin.x, rect->origin.y + rect->size.height, 0.0, 1.0 };
+ vertices[3] = (GskVulkanVertex) { rect->origin.x, rect->origin.y + rect->size.height, 0.0, 1.0 };
+ vertices[4] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y, 1.0, 0.0 };
+ vertices[5] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y + rect->size.height, 1.0, 1.0 };
+}
+
+gsize
+gsk_vulkan_blend_pipeline_draw (GskVulkanBlendPipeline *pipeline,
+ VkCommandBuffer command_buffer,
+ gsize offset,
+ gsize n_commands)
+{
+ vkCmdDraw (command_buffer,
+ n_commands * 6, 1,
+ offset, 0);
+
+ return n_commands * 6;
+}
#ifndef __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__
#define __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__
-#include <gdk/gdk.h>
+#include <graphene.h>
#include "gskvulkanpipelineprivate.h"
const char *shader_name,
VkRenderPass render_pass);
+gsize gsk_vulkan_blend_pipeline_count_vertex_data (GskVulkanBlendPipeline *pipeline);
+void gsk_vulkan_blend_pipeline_collect_vertex_data (GskVulkanBlendPipeline *pipeline,
+ guchar *data,
+ const graphene_rect_t *rect);
+gsize gsk_vulkan_blend_pipeline_draw (GskVulkanBlendPipeline *pipeline,
+ VkCommandBuffer command_buffer,
+ gsize offset,
+ gsize n_commands);
+
G_END_DECLS
#endif /* __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__ */
VkDevice device;
- g_return_val_if_fail (!g_type_is_a (pipeline_type, GSK_TYPE_VULKAN_PIPELINE), NULL);
+ g_return_val_if_fail (g_type_is_a (pipeline_type, GSK_TYPE_VULKAN_PIPELINE), NULL);
g_return_val_if_fail (layout != NULL, NULL);
g_return_val_if_fail (shader_name != NULL, NULL);
g_return_val_if_fail (render_pass != VK_NULL_HANDLE, NULL);
}
static gsize
-gsk_vulkan_renderer_count_vertices (GskVulkanRender *self)
+gsk_vulkan_renderer_count_vertex_data (GskVulkanRender *self)
{
- gsize count;
+ gsize n_bytes;
GSList *l;
- count = 0;
+ n_bytes = 0;
for (l = self->render_passes; l; l = l->next)
{
- count += gsk_vulkan_render_pass_count_vertices (l->data);
+ n_bytes += gsk_vulkan_render_pass_count_vertex_data (l->data);
}
- return count;
+ return n_bytes;
}
static GskVulkanBuffer *
-gsk_vulkan_render_collect_vertices (GskVulkanRender *self)
+gsk_vulkan_render_collect_vertex_data (GskVulkanRender *self)
{
GskVulkanBuffer *buffer;
- GskVulkanVertex *vertices;
+ guchar *data;
GSList *l;
- gsize offset, count;
+ gsize offset, n_bytes;
offset = 0;
- count = gsk_vulkan_renderer_count_vertices (self);
- buffer = gsk_vulkan_buffer_new (self->vulkan, sizeof (GskVulkanVertex) * count);
- vertices = (GskVulkanVertex *) gsk_vulkan_buffer_map (buffer);
+ n_bytes = gsk_vulkan_renderer_count_vertex_data (self);
+ buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes);
+ data = gsk_vulkan_buffer_map (buffer);
for (l = self->render_passes; l; l = l->next)
{
- offset += gsk_vulkan_render_pass_collect_vertices (l->data, vertices, offset, count - offset);
- g_assert (offset <= count);
+ offset += gsk_vulkan_render_pass_collect_vertex_data (l->data, data, offset, n_bytes - offset);
+ g_assert (offset <= n_bytes);
}
gsk_vulkan_buffer_unmap (buffer);
command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
- buffer = gsk_vulkan_render_collect_vertices (self);
+ buffer = gsk_vulkan_render_collect_vertex_data (self);
vkCmdSetViewport (command_buffer,
0,
},
VK_SUBPASS_CONTENTS_INLINE);
- vkCmdBindVertexBuffers (command_buffer,
- 0,
- 1,
- (VkBuffer[1]) {
- gsk_vulkan_buffer_get_buffer (buffer)
- },
- (VkDeviceSize[1]) { 0 });
-
for (l = self->render_passes; l; l = l->next)
{
- gsk_vulkan_render_pass_draw (l->data, self, self->layout, command_buffer);
+ gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
}
vkCmdEndRenderPass (command_buffer);
#include "gskvulkanrenderpassprivate.h"
+#include "gskvulkanblendpipelineprivate.h"
#include "gskvulkanimageprivate.h"
#include "gskrendernodeprivate.h"
#include "gskrenderer.h"
}
gsize
-gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self)
+gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
{
- return self->render_ops->len * 6;
-}
+ GskVulkanOp *op;
+ gsize n_bytes;
+ guint i;
-static gsize
-gsk_vulkan_render_op_collect_vertices (GskVulkanOpRender *op,
- GskVulkanVertex *vertices)
-{
- graphene_rect_t bounds;
+ n_bytes = 0;
+ for (i = 0; i < self->render_ops->len; i++)
+ {
+ op = &g_array_index (self->render_ops, GskVulkanOp, i);
- gsk_render_node_get_bounds (op->node, &bounds);
+ switch (op->type)
+ {
+ case GSK_VULKAN_OP_FALLBACK:
+ case GSK_VULKAN_OP_SURFACE:
+ case GSK_VULKAN_OP_TEXTURE:
+ case GSK_VULKAN_OP_COLOR:
+ op->render.vertex_count = gsk_vulkan_blend_pipeline_count_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline));
+ n_bytes += op->render.vertex_count;
+ break;
- vertices[0] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y, 0.0, 0.0 };
- vertices[1] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y, 1.0, 0.0 };
- vertices[2] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y + bounds.size.height, 0.0, 1.0 };
- vertices[3] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y + bounds.size.height, 0.0, 1.0 };
- vertices[4] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y, 1.0, 0.0 };
- vertices[5] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, 1.0, 1.0 };
+ default:
+ g_assert_not_reached ();
+ case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
+ case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
+ continue;
+ }
+ }
- return 6;
+ return n_bytes;
}
gsize
-gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
- GskVulkanVertex *vertices,
- gsize offset,
- gsize total)
+gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
+ guchar *data,
+ gsize offset,
+ gsize total)
{
GskVulkanOp *op;
- gsize n;
+ gsize n_bytes;
guint i;
- n = 0;
+ n_bytes = 0;
for (i = 0; i < self->render_ops->len; i++)
{
op = &g_array_index (self->render_ops, GskVulkanOp, i);
case GSK_VULKAN_OP_SURFACE:
case GSK_VULKAN_OP_TEXTURE:
case GSK_VULKAN_OP_COLOR:
- op->render.vertex_offset = offset + n;
- op->render.vertex_count = gsk_vulkan_render_op_collect_vertices (&op->render, vertices + n + offset);
+ {
+ graphene_rect_t bounds;
+
+ gsk_render_node_get_bounds (op->render.node, &bounds);
+ op->render.vertex_offset = offset + n_bytes;
+ gsk_vulkan_blend_pipeline_collect_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline),
+ data + n_bytes + offset,
+ &bounds);
+ n_bytes += op->render.vertex_count;
+ }
break;
default:
continue;
}
- n += op->render.vertex_count;
- g_assert (n + offset <= total);
+ g_assert (n_bytes + offset <= total);
}
- return n;
+ return n_bytes;
}
void
void
gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
GskVulkanRender *render,
+ GskVulkanBuffer *vertex_buffer,
GskVulkanPipelineLayout *layout,
VkCommandBuffer command_buffer)
{
GskVulkanPipeline *current_pipeline = NULL;
+ gsize current_draw_index = 0;
GskVulkanOp *op;
guint i;
vkCmdBindPipeline (command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
gsk_vulkan_pipeline_get_pipeline (current_pipeline));
+ vkCmdBindVertexBuffers (command_buffer,
+ 0,
+ 1,
+ (VkBuffer[1]) {
+ gsk_vulkan_buffer_get_buffer (vertex_buffer)
+ },
+ (VkDeviceSize[1]) { op->render.vertex_offset });
+ current_draw_index = 0;
}
- vkCmdDraw (command_buffer,
- op->render.vertex_count, 1,
- op->render.vertex_offset, 0);
+ current_draw_index += gsk_vulkan_blend_pipeline_draw (GSK_VULKAN_BLEND_PIPELINE (current_pipeline),
+ command_buffer,
+ current_draw_index, 1);
break;
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
#include <gdk/gdk.h>
#include <gsk/gskrendernode.h>
-#include "gsk/gskvulkancommandpoolprivate.h"
+#include "gsk/gskvulkanbufferprivate.h"
#include "gsk/gskvulkanrenderprivate.h"
G_BEGIN_DECLS
GskVulkanRender *render,
GskVulkanUploader *uploader);
-gsize gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self);
-gsize gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
- GskVulkanVertex *vertices,
+gsize gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self);
+gsize gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
+ guchar *data,
gsize offset,
gsize total);
GskVulkanRender *render);
void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
GskVulkanRender *render,
+ GskVulkanBuffer *vertex_buffer,
GskVulkanPipelineLayout *layout,
VkCommandBuffer command_buffer);
} GskVulkanPipelineType;
typedef struct _GskVulkanRender GskVulkanRender;
-typedef struct _GskVulkanVertex GskVulkanVertex;
-
-struct _GskVulkanVertex
-{
- float x;
- float y;
- float tex_x;
- float tex_y;
-};
GskVulkanRender * gsk_vulkan_render_new (GskRenderer *renderer,
GdkVulkanContext *context);